﻿//using Destiny.Core.Flow.IdentityServer;
//using Destiny.Core.Flow.IdentityServer.IdentityServerFour;
//using IdentityModel;
//using IdentityServer4.Extensions;
//using IdentityServer4.Services;
//using IdentityServer4.Stores;
//using Microsoft.AspNetCore.Authentication;
//using Microsoft.AspNetCore.Http;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;

//namespace Destiny.Core.Flow.IdentityServer.Service.Account
//{
//    public class AccountService: IAccountService
//    {
//        private readonly IClientStore _clientStore;
//        private readonly IIdentityServerInteractionService _interaction;
//        private readonly IHttpContextAccessor _httpContextAccessor;
//        private readonly IAuthenticationSchemeProvider _schemeProvider;

//        public AccountService(IClientStore clientStore, IIdentityServerInteractionService interaction, IHttpContextAccessor httpContextAccessor, IAuthenticationSchemeProvider schemeProvider)
//        {
//            _clientStore = clientStore;
//            _interaction = interaction;
//            _httpContextAccessor = httpContextAccessor;
//            _schemeProvider = schemeProvider;
//        }

//        public async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)
//        {
//            var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
//            if (context?.IdP != null)
//            {
//                // this is meant to short circuit the UI and only trigger the one external IdP
//                return new LoginViewModel
//                {
//                    EnableLocalLogin = false,
//                    ReturnUrl = returnUrl,
//                    Username = context?.LoginHint,
//                    ExternalProviders = new ExternalProvider[] { new ExternalProvider { AuthenticationScheme = context.IdP } }
//                };
//            }

//            var schemes = await _schemeProvider.GetAllSchemesAsync();

//            var providers = schemes
//                .Where(x => x.DisplayName != null)
//                .Select(x => new ExternalProvider
//                {
//                    DisplayName = x.DisplayName,
//                    AuthenticationScheme = x.Name
//                }).ToList();

//            var allowLocal = true;
//            if (context?.Client.ClientId != null)
//            {
//                var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);
//                if (client != null)
//                {
//                    allowLocal = client.EnableLocalLogin;

//                    if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())
//                    {
//                        providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();
//                    }
//                }
//            }

//            return new LoginViewModel
//            {
//                AllowRememberLogin = AccountOptions.AllowRememberLogin,
//                EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,
//                ReturnUrl = returnUrl,
//                Username = context?.LoginHint,
//                ExternalProviders = providers.ToArray()
//            };
//        }

//        public async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)
//        {
//            var vm = await BuildLoginViewModelAsync(model.ReturnUrl);
//            vm.Username = model.Username;
//            vm.RememberLogin = model.RememberLogin;
//            return vm;
//        }

//        public async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)
//        {
//            var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };

//            var user = _httpContextAccessor.HttpContext.User;
//            if (user?.Identity.IsAuthenticated != true)
//            {
//                // if the user is not authenticated, then just show logged out page
//                vm.ShowLogoutPrompt = false;
//                return vm;
//            }

//            var context = await _interaction.GetLogoutContextAsync(logoutId);
//            if (context?.ShowSignoutPrompt == false)
//            {
//                // it's safe to automatically sign-out
//                vm.ShowLogoutPrompt = false;
//                return vm;
//            }

//            // show the logout prompt. this prevents attacks where the user
//            // is automatically signed out by another malicious web page.
//            return vm;
//        }

//        public async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)
//        {
//            // get context information (client name, post logout redirect URI and iframe for federated signout)
//            var logout = await _interaction.GetLogoutContextAsync(logoutId);

//            var vm = new LoggedOutViewModel
//            {
//                AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,
//                PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,
//                ClientName = logout?.ClientId,
//                SignOutIframeUrl = logout?.SignOutIFrameUrl,
//                LogoutId = logoutId
//            };

//            var user = _httpContextAccessor.HttpContext.User;
//            if (user?.Identity.IsAuthenticated == true)
//            {
//                var idp = user.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;
//                if (idp != null && idp != IdentityServer4.IdentityServerConstants.LocalIdentityProvider)
//                {
//                    var providerSupportsSignout = await _httpContextAccessor.HttpContext.GetSchemeSupportsSignOutAsync(idp);
//                    if (providerSupportsSignout)
//                    {
//                        if (vm.LogoutId == null)
//                        {
//                            // if there's no current logout context, we need to create one
//                            // this captures necessary info from the current logged in user
//                            // before we signout and redirect away to the external IdP for signout
//                            vm.LogoutId = await _interaction.CreateLogoutContextAsync();
//                        }

//                        vm.ExternalAuthenticationScheme = idp;
//                    }
//                }
//            }

//            return vm;
//        }
//    }
//}
